/**
 * 报表AI助手页面组件 - 企业财务数据分析与智能问答界面
 *
 * 开发人员：郭畅
 * 开发时间：2025-11-10 至 2025-11-15
 * 模块职责：提供AI智能助手的完整交互界面，包括聊天对话、文档上传、工具调用等功能
 *
 * 技术要点：
 * - AI聊天界面和流式对话实现
 * - 多模态文档上传和解析功能
 * - Markdown内容渲染和格式化显示
 * - 工具调用徽章和快捷问题按钮
 * - 前后端WebSocket和SSE通信集成
 *
 * 开发故事：负责报表AI助手的完整前端界面实现，与后端AI聊天服务深度集成，为用户提供智能的财务数据分析和问答体验。
 */
<template>
  <div class="ai-chat-page">
    <!-- 页面标题 -->
    <div class="page-header">
      <h1 class="page-title">AI智能助手</h1>
      <p class="page-subtitle">企业财务数据分析与智能问答</p>
    </div>

    <!-- 聊天容器 -->
    <div class="chat-container">
      <!-- 聊天消息区域 -->
      <div class="chat-messages" ref="chatMessages">
        <div v-for="(message, index) in messages" :key="index" class="message-wrapper">
          <!-- 用户消息 -->
          <div v-if="message.role === 'user'" class="message user-message">
            <div class="message-avatar">
              <i class="el-icon-user-solid"></i>
            </div>
            <div class="message-content">
              <div class="message-text">{{ message.content }}</div>
              <div class="message-time">{{ formatTime(message.timestamp) }}</div>
            </div>
          </div>

          <!-- AI消息 -->
          <div v-else-if="message.role === 'assistant'" class="message assistant-message">
            <div class="message-avatar">
              <i class="el-icon-service"></i>
            </div>
            <div class="message-content">
              <!-- 工具调用徽章（顶部去重展示） -->
              <div v-if="message.toolBadges && message.toolBadges.length" class="tool-badges">
                <span v-for="tb in message.toolBadges" :key="tb" class="tool-badge">
                  <i class="el-icon-tools"></i>{{ getToolDisplayName(tb) }}
                </span>
              </div>
              
              <!-- AI回复内容 -->
              <div v-if="message.content" class="message-text" v-html="renderMarkdown(message.content)"></div>
              
              <!-- 快捷问题按钮 -->
              <div v-if="message.quickActions && message.quickActions.length > 0" class="quick-actions">
                <div class="quick-actions-title">您可以问我：</div>
                <div class="quick-actions-buttons">
                  <el-button
                    v-for="(action, idx) in message.quickActions"
                    :key="idx"
                    size="small"
                    @click="sendQuickAction(action)"
                    class="quick-action-btn">
                    {{ action }}
                  </el-button>
                </div>
              </div>
              
              <div class="message-time">{{ formatTime(message.timestamp) }}</div>
            </div>
          </div>
        </div>

        <!-- 加载状态 -->
        <div v-if="isLoading" class="loading-wrapper">
          <div class="message assistant-message">
            <div class="message-avatar">
              <i class="el-icon-service"></i>
            </div>
            <div class="message-content">
              <div class="loading-indicator">
                <div class="loading-dots">
                  <span></span>
                  <span></span>
                  <span></span>
                </div>
                <span>AI正在分析中</span>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 输入区域 -->
      <div class="chat-input-area">
        <!-- 文件上传区域 -->
        <div class="file-upload-area" v-if="showFileUpload">
          <el-upload
            class="file-uploader"
            drag
            :action="uploadUrl"
            :headers="uploadHeaders"
            :on-success="handleFileUpload"
            :on-error="handleUploadError"
            :before-upload="beforeUpload"
            :show-file-list="false"
            accept=".pdf,.doc,.docx,.txt,.png,.jpg,.jpeg">
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
            <div class="el-upload__tip">支持PDF、DOC、DOCX、TXT、PNG、JPG格式</div>
          </el-upload>
        </div>

        <!-- 输入框 -->
        <div class="input-container">
          <div class="input-actions">
            <el-button 
              size="small" 
              :type="showFileUpload ? 'primary' : ''"
              @click="toggleFileUpload"
              icon="el-icon-upload">
              {{ showFileUpload ? '隐藏上传' : '上传文件' }}
            </el-button>
            <el-button 
              size="small" 
              @click="clearChat"
              icon="el-icon-delete">
              清空对话
            </el-button>
          </div>
          
          <div class="input-wrapper">
            <el-input
              v-model="inputMessage"
              type="textarea"
              :rows="3"
              placeholder="请输入您的问题，AI将为您分析企业数据... (按Enter发送)"
              @keydown.enter="handleEnterKey"
              :disabled="isLoading">
            </el-input>
            <el-button 
              type="primary" 
              @click="sendMessage"
              :loading="isLoading"
              :disabled="!inputMessage.trim()"
              class="send-button">
              <i class="el-icon-s-promotion"></i>
              发送
            </el-button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import http from '../api/http'
import * as marked from 'marked'

export default {
  name: 'AiChat',
  data() {
    return {
      enterpriseId: parseInt(localStorage.getItem('enterpriseId')) || 1,
      messages: [],
      inputMessage: '',
      isLoading: false,
      showFileUpload: false,
      uploadUrl: '',
      uploadHeaders: {}
    }
  },
  created() {
    this.initializeChat()
    this.setupUpload()
  },
  methods: {
    initializeChat() {
      // 添加欢迎消息
      this.messages.push({
        role: 'assistant',
        content: '您好！我是智融财务管理系统的AI助手，专注于为您提供专业的财务数据分析和业务咨询服务。',
        timestamp: new Date(),
        toolCalls: [],
        quickActions: [
          '查询本月支付订单统计',
          '分析当前融资申请状态',
          '查看企业产品列表',
          '解读最新财务数据'
        ]
      })
    },

    setupUpload() {
      this.uploadUrl = `/api/enterprises/${this.enterpriseId}/ai/upload`
      this.uploadHeaders = {
        'X-Enterprise-Id': this.enterpriseId.toString(),
        'X-User-Id': localStorage.getItem('userId') || '1'
      }
    },

    async sendMessage() {
      if (!this.inputMessage.trim() || this.isLoading) return

      const userMessage = {
        role: 'user',
        content: this.inputMessage.trim(),
        timestamp: new Date()
      }

      this.messages.push(userMessage)
      this.inputMessage = ''
      this.isLoading = true

      try {
        // 使用流式API
        await this.sendStreamMessage()
      } catch (error) {
        console.error('发送消息失败:', error)
        this.$message.error('发送失败，请重试')
        
        // 添加错误消息
        this.messages.push({
          id: Date.now() + 1,
          role: 'assistant',
          content: '抱歉，我暂时无法回答您的问题。',
          timestamp: new Date()
        })
      } finally {
        this.isLoading = false
        this.$nextTick(() => {
          this.scrollToBottom()
        })
      }
    },

    async sendStreamMessage() {
      const response = await fetch(`/api/enterprises/${this.enterpriseId}/ai/chat/stream`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-Enterprise-Id': localStorage.getItem('enterpriseId') || '1',
          'X-User-Id': localStorage.getItem('userId') || '1'
        },
        body: JSON.stringify({
          messages: this.messages.map(msg => ({
            role: msg.role,
            content: msg.content
          }))
        })
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      // 创建AI助手消息（但不立即添加到messages，等有内容时再添加）
      const assistantMessage = {
        id: Date.now(),
        role: 'assistant',
        content: '',
        timestamp: new Date(),
        toolCalls: [],
        toolBadges: []
      };
      console.log('创建了AI消息对象:', assistantMessage);

      const reader = response.body.getReader();
      const decoder = new TextDecoder();
      let buffer = '';

      try {
        let currentEvent = null;
        let currentData = null;
        
        while (true) {
          const { done, value } = await reader.read();
          if (done) break;

          buffer += decoder.decode(value, { stream: true });
          const lines = buffer.split('\n');
          buffer = lines.pop() || '';

          for (const line of lines) {
            const trimmed = line.trim();
            
            // 空行表示一个完整事件结束
            if (!trimmed) {
              if (currentEvent && currentData) {
                try {
                  const eventData = JSON.parse(currentData);
                  console.log('解析SSE事件:', currentEvent, eventData);
                  this.handleStreamEvent({
                    event: currentEvent,
                    data: eventData
                  }, assistantMessage);
                } catch (e) {
                  console.warn('解析SSE数据失败:', currentData, e);
                }
              }
              // 重置状态
              currentEvent = null;
              currentData = null;
              continue;
            }

            if (trimmed.startsWith('event:')) {
              // 兼容 'event: start' 和 'event:start'
              currentEvent = trimmed.substring(6).trim();
              console.log('读取event:', currentEvent);
            } else if (trimmed.startsWith('data:')) {
              // 兼容 'data: {...}' 和 'data:{...}'
              currentData = trimmed.substring(5).trim();
              console.log('读取data:', currentData);
              
              if (currentData === '[DONE]') {
                currentEvent = null;
                currentData = null;
                continue;
              }
            }
          }
        }
        
        // 处理最后可能未结束的事件
        if (currentEvent && currentData) {
          try {
            const eventData = JSON.parse(currentData);
            console.log('解析最后的SSE事件:', currentEvent, eventData);
            this.handleStreamEvent({
              event: currentEvent,
              data: eventData
            }, assistantMessage);
          } catch (e) {
            console.warn('解析最后的SSE数据失败:', currentData, e);
          }
        }
      } finally {
        reader.releaseLock();
        this.scrollToBottom();
      }
    },

    handleStreamEvent(eventInfo, assistantMessage) {
      console.log('处理流式事件:', eventInfo);
      
      switch (eventInfo.event) {
        case 'start':
          console.log('开始接收流式响应');
          break;
          
        case 'tool_call':
          if (eventInfo.data) {
            // 初始化徽章容器
            if (!assistantMessage.toolBadges) assistantMessage.toolBadges = []
            const tool = eventInfo.data.tool
            // 去重：只保留唯一工具名
            if (tool && !assistantMessage.toolBadges.includes(tool)) {
              assistantMessage.toolBadges.push(tool)
            }
          }
          break;
          
        case 'content':
          if (eventInfo.data) {
            const newContent = eventInfo.data.content || '';
            
            // 如果是第一次添加内容，将消息添加到messages数组
            if (assistantMessage.content === '') {
              this.messages.push(assistantMessage);
              console.log('首次添加内容，将消息添加到数组');
            }
            
            assistantMessage.content += newContent;
            console.log('添加内容:', newContent);
            console.log('当前总内容:', assistantMessage.content);
            
            // 强制Vue更新并滚动
            this.$forceUpdate();
            this.$nextTick(() => {
              this.scrollToBottom();
            });
          }
          break;
          
        case 'done':
          console.log('流式响应完成');
          break;
          
        case 'error':
          if (eventInfo.data) {
            assistantMessage.content = '抱歉，处理您的请求时出现错误: ' + (eventInfo.data.error || '未知错误');
          }
          break;
      }
    },

    handleFileUpload(response, file) {
      if (response.code === 0) {
        this.$message.success('文件上传成功')
        
        // 自动发送文件内容给AI
        const fileMessage = `我上传了一个文件：${response.data.fileName}\n\n文件内容：\n${response.data.content}`
        this.inputMessage = fileMessage
        this.showFileUpload = false
        this.sendMessage()
      } else {
        this.$message.error(response.message || '文件上传失败')
      }
    },

    handleUploadError(error) {
      console.error('文件上传错误:', error)
      this.$message.error('文件上传失败')
    },

    beforeUpload(file) {
      const isValidType = ['pdf', 'doc', 'docx', 'txt', 'png', 'jpg', 'jpeg'].includes(
        file.name.split('.').pop().toLowerCase()
      )
      
      if (!isValidType) {
        this.$message.error('不支持的文件格式')
        return false
      }

      const isLt10M = file.size / 1024 / 1024 < 10
      if (!isLt10M) {
        this.$message.error('文件大小不能超过10MB')
        return false
      }

      return true
    },

    toggleFileUpload() {
      this.showFileUpload = !this.showFileUpload
    },

    clearChat() {
      this.$confirm('确定要清空所有对话记录吗？', '确认清空', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.messages = []
        this.initializeChat()
        this.$message.success('对话已清空')
      })
    },

    formatTime(timestamp) {
      return new Date(timestamp).toLocaleTimeString('zh-CN', {
        hour: '2-digit',
        minute: '2-digit'
      })
    },

    getToolDisplayName(functionName) {
      const toolNames = {
        'get_enterprise_info': '获取企业信息',
        'get_payment_orders': '获取支付订单',
        'get_financing_requests': '获取融资申请',
        'get_finance_reports': '获取财务报表',
        'get_products': '获取产品信息'
      }
      return toolNames[functionName] || functionName
    },

    renderMarkdown(content) {
      if (!content) return ''
      
      // 简单的Markdown渲染
      return marked.parse(content, {
        breaks: true,
        gfm: true
      })
    },

    scrollToBottom() {
      const chatMessages = this.$refs.chatMessages
      if (chatMessages) {
        chatMessages.scrollTop = chatMessages.scrollHeight
      }
    },

    sendQuickAction(action) {
      this.inputMessage = action
      this.sendMessage()
    },

    handleEnterKey(event) {
      // 如果没有按住Shift键，则发送消息
      if (!event.shiftKey && this.inputMessage.trim() && !this.isLoading) {
        event.preventDefault()
        this.sendMessage()
      }
      // 如果按住Shift+Enter，则允许换行（默认行为）
    }
  }
}
</script>

<style scoped>
.ai-chat-page {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--bg-primary);
}

/* 工具徽章（顶部紧凑展示） */
.tool-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 8px;
}

.tool-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  font-size: 12px;
  color: #fff;
  background: linear-gradient(135deg, #3d7eff, #2c5ce6);
  border-radius: 999px;
  box-shadow: 0 4px 10px rgba(60, 96, 245, 0.25);
}

.tool-badge i {
  font-size: 12px;
}

.page-header {
  padding: 24px 24px 16px;
  background: white;
  border-bottom: 1px solid var(--border-color);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.page-title {
  font-size: 24px;
  font-weight: 700;
  background: var(--primary-gradient);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  margin: 0 0 8px 0;
}

.page-subtitle {
  font-size: 14px;
  color: var(--text-secondary);
  margin: 0;
}

.chat-container {
  flex: 1;
  display: flex;
  flex-direction: column;
  max-width: 1200px;
  margin: 0 auto;
  width: 100%;
  background: white;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
  background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
}

.message-wrapper {
  margin-bottom: 20px;
}

.message {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  animation: fadeInUp 0.3s ease-out;
}

.message-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  flex-shrink: 0;
}

.user-message .message-avatar {
  background: var(--primary-gradient);
  color: white;
}

.assistant-message .message-avatar {
  background: var(--success-gradient);
  color: white;
}

.message-content {
  flex: 1;
  max-width: 80%;
}

.user-message .message-content {
  margin-left: auto;
  text-align: right;
}

.message-text {
  background: white;
  padding: 12px 16px;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  line-height: 1.6;
  word-wrap: break-word;
}

.user-message .message-text {
  background: var(--primary-gradient);
  color: white;
  border-radius: 12px 12px 4px 12px;
}

.assistant-message .message-text {
  background: white;
  color: var(--text-primary);
  border-radius: 12px 12px 12px 4px;
  border: 1px solid var(--border-color);
}

.message-time {
  font-size: 12px;
  color: var(--text-tertiary);
  margin-top: 4px;
}

/* 工具调用样式 */
.tool-calls {
  margin-bottom: 12px;
}

.tool-call {
  background: var(--bg-primary);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 8px;
}

.tool-call-header {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  color: var(--primary-color);
  margin-bottom: 8px;
}

.tool-call-details {
  font-size: 13px;
  color: var(--text-secondary);
}

.tool-call-args,
.tool-call-result {
  margin-bottom: 4px;
}

.tool-call-result {
  background: rgba(6, 192, 95, 0.1);
  padding: 8px;
  border-radius: 4px;
  border-left: 3px solid var(--success-color);
}

/* 快捷问题按钮 */
.quick-actions {
  margin-top: 16px;
  padding: 16px;
  background: linear-gradient(135deg, rgba(255, 209, 0, 0.05) 0%, rgba(6, 192, 95, 0.05) 100%);
  border-radius: 12px;
  border: 1px solid var(--border-color);
}

.quick-actions-title {
  font-size: 13px;
  color: var(--text-secondary);
  margin-bottom: 12px;
  font-weight: 600;
}

.quick-actions-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.quick-action-btn {
  background: white;
  border: 1px solid var(--border-color);
  color: var(--text-primary);
  border-radius: 8px;
  padding: 8px 16px;
  font-size: 13px;
  transition: all var(--transition-normal);
}

.quick-action-btn:hover {
  background: var(--primary-gradient);
  color: white;
  border-color: var(--primary-color);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(255, 209, 0, 0.3);
}

/* 加载状态 */
.loading-wrapper {
  margin-bottom: 20px;
}

.loading-indicator {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--text-secondary);
  font-size: 14px;
}

.loading-dots {
  display: flex;
  gap: 4px;
}

.loading-dots span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--primary-color);
  animation: bounce 1.4s infinite ease-in-out both;
}

.loading-dots span:nth-child(1) {
  animation-delay: -0.32s;
}

.loading-dots span:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes bounce {
  0%, 80%, 100% {
    transform: scale(0);
    opacity: 0.5;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

/* 输入区域 */
.chat-input-area {
  border-top: 1px solid var(--border-color);
  background: white;
  padding: 20px;
}

.file-upload-area {
  margin-bottom: 16px;
  padding: 20px;
  border: 2px dashed var(--border-color);
  border-radius: 8px;
  background: var(--bg-primary);
  transition: all var(--transition-normal);
}

.file-upload-area:hover {
  border-color: var(--primary-color);
  background: rgba(255, 209, 0, 0.05);
}

.file-uploader {
  width: 100%;
}

.input-container {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.input-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

.input-wrapper {
  display: flex;
  gap: 12px;
  align-items: flex-end;
}

.input-wrapper .el-textarea {
  flex: 1;
}

.send-button {
  height: 40px;
  padding: 0 20px;
  border-radius: 8px;
  font-weight: 600;
}

/* Markdown渲染样式 */
:deep(.message-text h1),
:deep(.message-text h2),
:deep(.message-text h3) {
  margin: 16px 0 8px 0;
  color: var(--text-primary);
}

:deep(.message-text h1) {
  font-size: 20px;
  border-bottom: 2px solid var(--primary-color);
  padding-bottom: 8px;
}

:deep(.message-text h2) {
  font-size: 18px;
  color: var(--primary-color);
}

:deep(.message-text h3) {
  font-size: 16px;
  color: var(--text-primary);
}

:deep(.message-text p) {
  margin: 8px 0;
  line-height: 1.6;
}

:deep(.message-text ul),
:deep(.message-text ol) {
  margin: 8px 0;
  padding-left: 20px;
}

:deep(.message-text li) {
  margin: 4px 0;
}

:deep(.message-text code) {
  background: var(--bg-primary);
  padding: 2px 6px;
  border-radius: 4px;
  font-family: 'Courier New', monospace;
  font-size: 13px;
}

:deep(.message-text pre) {
  background: var(--bg-primary);
  padding: 12px;
  border-radius: 8px;
  overflow-x: auto;
  margin: 12px 0;
}

:deep(.message-text blockquote) {
  border-left: 4px solid var(--primary-color);
  padding-left: 16px;
  margin: 12px 0;
  color: var(--text-secondary);
  font-style: italic;
}

:deep(.message-text table) {
  width: 100%;
  border-collapse: collapse;
  margin: 12px 0;
}

:deep(.message-text th),
:deep(.message-text td) {
  border: 1px solid var(--border-color);
  padding: 8px 12px;
  text-align: left;
}

:deep(.message-text th) {
  background: var(--bg-primary);
  font-weight: 600;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .chat-container {
    margin: 0;
    box-shadow: none;
  }
  
  .page-header {
    padding: 16px;
  }
  
  .chat-messages {
    padding: 16px;
  }
  
  .message-content {
    max-width: 90%;
  }
  
  .chat-input-area {
    padding: 16px;
  }
  
  .input-wrapper {
    flex-direction: column;
  }
  
  .send-button {
    width: 100%;
  }
}

/* 动画效果 */
@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 滚动条样式 */
.chat-messages::-webkit-scrollbar {
  width: 6px;
}

.chat-messages::-webkit-scrollbar-track {
  background: var(--bg-primary);
}

.chat-messages::-webkit-scrollbar-thumb {
  background: var(--border-color);
  border-radius: 3px;
}

.chat-messages::-webkit-scrollbar-thumb:hover {
  background: var(--text-tertiary);
}
</style>
